package com.concurrency.example.aqs;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Semaphore;

/**
 * Semaphore 信号量控制对某种资源或者操作同时处理的线程数量
 * 利用Semaphore可以把普通容器变成有界阻塞容器
 * @Auther: xuwei
 * @Date: 2018/11/30 10:31
 */
public class BoundedHashSet<T> {
    private final Set<T> set;
    private final Semaphore semaphore;

    /**
     * @param bound 边界大小
     */
    public BoundedHashSet(int bound) {
        this.set = Collections.synchronizedSet(new HashSet<>());
        this.semaphore = new Semaphore(bound);
    }

    public boolean add(T t) {
        //获取许可，如果没有许可，线程会阻塞
        try{
            semaphore.acquire();
        }catch(InterruptedException e){
            e.printStackTrace();
        }

        boolean res = set.add(t);
        if (!res) {
            semaphore.release();
        }

        return res;
    }

    public boolean remove(Object o) {
        boolean res = set.remove(o);
        if (res) {
            semaphore.release();
        }
        return res;
    }

    public int size() {
        return set.size();
    }

    @Override
    public String toString() {
        return set.toString();
    }

    public static void main(String[] args) {
        BoundedHashSet<Object> set = new BoundedHashSet<>(5);
        set.add(12);
        set.add(13);
        set.add(14);
        set.add(15);
        set.add(16);
        /* 因为set的边界是5，所以下面的数据插不进去，当前线程会阻塞 */
        set.add(17);
        System.out.println(set);


    }
}
